home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.6) '''The main module for the Orca screen reader.''' __id__ = '$Id: orca.py 4285 2008-10-12 20:42:37Z wwalker $' __version__ = '$Revision: 4285 $' __date__ = '$Date: 2008-10-12 16:42:37 -0400 (Sun, 12 Oct 2008) $' __copyright__ = 'Copyright (c) 2004-2008 Sun Microsystems Inc.' __license__ = 'LGPL' import sys sys.argv[0] = 'orca' import pygtk pygtk.require('2.0') try: import gtk except: pass try: import mouse_review except RuntimeError: pass import getopt import gnome import os import signal import time import unicodedata import pyatspi import braille import debug import httpserver import keynames import keybindings import mag import orca_state import platform import settings import speech from input_event import BrailleEvent from input_event import KeyboardEvent from input_event import MouseButtonEvent from input_event import keyEventToString if settings.useDBus: import dbusserver from orca_i18n import _ if settings.debugMemoryUsage: import gc gc.set_debug(gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_COLLECTABLE | gc.DEBUG_INSTANCES | gc.DEBUG_OBJECTS | gc.DEBUG_SAVEALL) _userSettings = None _commandLineSettings = { } _PRESENTATION_MANAGERS = None _currentPresentationManager = -1 def _switchToPresentationManager(index): '''Switches to the given presentation manager. Arguments: - index: an index into _PRESENTATION_MANAGERS ''' global _currentPresentationManager, _currentPresentationManager, _currentPresentationManager if _currentPresentationManager >= 0: _PRESENTATION_MANAGERS[_currentPresentationManager].deactivate() _currentPresentationManager = index if _currentPresentationManager >= len(_PRESENTATION_MANAGERS): _currentPresentationManager = 0 elif _currentPresentationManager < 0: _currentPresentationManager = len(_PRESENTATION_MANAGERS) - 1 _PRESENTATION_MANAGERS[_currentPresentationManager].activate() def _switchToNextPresentationManager(script = None, inputEvent = None): '''Switches to the next presentation manager. Arguments: - inputEvent: the InputEvent instance that caused this to be called. Returns True indicating the event should be consumed. ''' _switchToPresentationManager(_currentPresentationManager + 1) return True def getScriptForApp(app): '''Get the script for the given application object from the current presentation manager. Arguments: - app: An application accessible. Returns a Script instance. ''' script = None if _currentPresentationManager >= 0: script = _PRESENTATION_MANAGERS[_currentPresentationManager].getScript(app) return script def setLocusOfFocus(event, obj, notifyPresentationManager = True): '''Sets the locus of focus (i.e., the object with visual focus) and notifies the current presentation manager of the change. Arguments: - event: if not None, the Event that caused this to happen - obj: the Accessible with the new locus of focus. - notifyPresentationManager: if True, propagate this event ''' if obj == orca_state.locusOfFocus: return None oldLocusOfFocus = orca_state.locusOfFocus try: oldLocusOfFocus.getRole() except: None if event and event.source and event.host_application and orca_state.activeScript else obj == orca_state.locusOfFocus oldLocusOfFocus = None orca_state.focusHistory = orca_state.focusHistory[:settings.focusHistoryLength - 1] orca_state.focusHistory.insert(0, oldLocusOfFocus) orca_state.locusOfFocus = obj try: app = orca_state.locusOfFocus.getApplication() except: None if event and event.source and event.host_application and orca_state.activeScript else obj == orca_state.locusOfFocus orca_state.locusOfFocus = None if event: debug.println(debug.LEVEL_FINE, "LOCUS OF FOCUS: None event='%s'" % event.type) else: debug.println(debug.LEVEL_FINE, 'LOCUS OF FOCUS: None event=None') if not app: appname = 'None' else: appname = "'" + app.name + "'" debug.println(debug.LEVEL_FINE, "LOCUS OF FOCUS: app=%s name='%s' role='%s'" % (appname, orca_state.locusOfFocus.name, orca_state.locusOfFocus.getRoleName())) if event: debug.println(debug.LEVEL_FINE, " event='%s'" % event.type) else: debug.println(debug.LEVEL_FINE, ' event=None') if notifyPresentationManager and _currentPresentationManager >= 0: _PRESENTATION_MANAGERS[_currentPresentationManager].locusOfFocusChanged(event, oldLocusOfFocus, orca_state.locusOfFocus) def visualAppearanceChanged(event, obj): """Called (typically by scripts) when the visual appearance of an object changes and notifies the current presentation manager of the change. This method should not be called for objects whose visual appearance changes solely because of focus -- setLocusOfFocus is used for that. Instead, it is intended mostly for objects whose notional 'value' has changed, such as a checkbox changing state, a progress bar advancing, a slider moving, text inserted, caret moved, etc. Arguments: - event: if not None, the Event that caused this to happen - obj: the Accessible whose visual appearance changed. """ if _currentPresentationManager >= 0: _PRESENTATION_MANAGERS[_currentPresentationManager].visualAppearanceChanged(event, obj) def _onChildrenChanged(e): '''Tracks children-changed events on the desktop to determine when apps start and stop. Arguments: - e: at-spi event from the at-api registry ''' desktop = pyatspi.Registry.getDesktop(0) if e.source == desktop: try: if desktop.childCount == 0: speech.speak(_('Goodbye.')) shutdown() return None debug.printException(debug.LEVEL_FINEST) shutdown() return None def _onMouseButton(e): '''Tracks mouse button events, stopping any speech in progress. Arguments: - e: at-spi event from the at-api registry ''' mouse_event = MouseButtonEvent(e) orca_state.lastInputEvent = mouse_event if mouse_event.pressed: speech.stop() def cycleDebugLevel(script = None, inputEvent = None): levels = [ debug.LEVEL_ALL, 'all', debug.LEVEL_FINEST, 'finest', debug.LEVEL_FINER, 'finer', debug.LEVEL_FINE, 'fine', debug.LEVEL_CONFIGURATION, 'configuration', debug.LEVEL_INFO, 'info', debug.LEVEL_WARNING, 'warning', debug.LEVEL_SEVERE, 'severe', debug.LEVEL_OFF, 'off'] try: levelIndex = levels.index(debug.debugLevel) + 2 except: levelIndex = 0 if levelIndex >= len(levels): levelIndex = 0 debug.debugLevel = levels[levelIndex] speech.speak('Debug level %s.' % levels[levelIndex + 1]) return True def exitLearnMode(self, inputEvent = None): '''Turns learn mode off. Returns True to indicate the input event has been consumed. ''' message = _('Exiting learn mode.') speech.speak(message) braille.displayMessage(message) settings.learnModeEnabled = False return True _keyBindings = None _orcaModifierPressed = False def isPrintableKey(event_string): '''Return an indication of whether this is an alphanumeric or punctuation key. Arguments: - event: the event string Returns True if this is an alphanumeric or punctuation key. ''' if event_string == 'space': reply = True else: unicodeString = event_string.decode('UTF-8') if not len(unicodeString) == 1 and unicodeString.isalnum() and unicodeString.isspace(): pass reply = unicodedata.category(unicodeString)[0] in ('P', 'S') debug.println(debug.LEVEL_FINEST, 'orca.isPrintableKey: returning: %s' % reply) return reply def isModifierKey(event_string): '''Return an indication of whether this is a modifier key. Arguments: - event: the event string Returns True if this is a modifier key ''' modifierKeys = [ 'Alt_L', 'Alt_R', 'Control_L', 'Control_R', 'Shift_L', 'Shift_R', 'Meta_L', 'Meta_R'] modifierKeys.extend(settings.orcaModifierKeys) reply = event_string in modifierKeys debug.println(debug.LEVEL_FINEST, 'orca.isModifierKey: returning: %s' % reply) return reply def isLockingKey(event_string): '''Return an indication of whether this is a locking key. Arguments: - event: the event string Returns True if this is a locking key. ''' lockingKeys = [ 'Caps_Lock', 'Num_Lock', 'Scroll_Lock'] if event_string in lockingKeys: pass reply = event_string not in settings.orcaModifierKeys debug.println(debug.LEVEL_FINEST, 'orca.isLockingKey: returning: %s' % reply) return reply def isFunctionKey(event_string): '''Return an indication of whether this is a function key. Arguments: - event: the event string Returns True if this is a function key. ''' functionKeys = [ 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12'] reply = event_string in functionKeys debug.println(debug.LEVEL_FINEST, 'orca.isFunctionKey: returning: %s' % reply) return reply def isActionKey(event_string): '''Return an indication of whether this is an action key. Arguments: - event: the event string Returns True if this is an action key. ''' actionKeys = [ 'Return', 'Escape', 'Tab', 'BackSpace', 'Delete', 'Page_Up', 'Page_Down', 'Home', 'End'] reply = event_string in actionKeys debug.println(debug.LEVEL_FINEST, 'orca.isActionKey: returning: %s' % reply) return reply def isNavigationKey(event_string): '''Return an indication of whether this is a navigation (arrow) key or if the user has the Orca modifier key held done. Arguments: - event: the event string - modifiers: key modifiers state Returns True if this is a navigation key. ''' navigationKeys = [ 'Left', 'Right', 'Up', 'Down'] if not event_string in navigationKeys: pass reply = _orcaModifierPressed debug.println(debug.LEVEL_FINEST, 'orca.isNavigationKey: returning: %s' % reply) return reply class KeyEventType: '''Definition of available key event types.''' PRINTABLE = 'PRINTABLE' MODIFIER = 'MODIFIER' LOCKING = 'LOCKING' LOCKING_LOCKED = 'LOCKING_LOCKED' LOCKING_UNLOCKED = 'LOCKING_UNLOCKED' FUNCTION = 'FUNCTION' ACTION = 'ACTION' NAVIGATION = 'NAVIGATION' def __init__(self): pass def keyEcho(event): '''If the keyEcho setting is enabled, check to see what type of key event it is and echo it via speech, if the user wants that type of key echoed. Uppercase keys will be spoken using the "uppercase" voice style, whereas lowercase keys will be spoken using the "default" voice style. Arguments: - event: an AT-SPI DeviceEvent ''' if orca_state.locusOfFocus and orca_state.locusOfFocus.getRole() == pyatspi.ROLE_PASSWORD_TEXT: return None event_string = event.event_string debug.println(debug.LEVEL_FINEST, 'orca.keyEcho: string to echo: %s' % event_string) if settings.enableKeyEcho: if isModifierKey(event_string): if not settings.enableModifierKeys: return None eventType = KeyEventType.MODIFIER elif isNavigationKey(event_string): if not settings.enableNavigationKeys: return None eventType = KeyEventType.NAVIGATION elif isPrintableKey(event_string): if not settings.enablePrintableKeys: return None eventType = KeyEventType.PRINTABLE elif isLockingKey(event_string): if not settings.enableLockingKeys: return None eventType = KeyEventType.LOCKING modifiers = event.modifiers if event_string == 'Caps_Lock': if modifiers & 1 << pyatspi.MODIFIER_SHIFTLOCK: eventType = KeyEventType.LOCKING_UNLOCKED else: eventType = KeyEventType.LOCKING_LOCKED elif event_string == 'Num_Lock': pass elif isFunctionKey(event_string): if not settings.enableFunctionKeys: return None eventType = KeyEventType.FUNCTION elif isActionKey(event_string): if not settings.enableActionKeys: return None eventType = KeyEventType.ACTION else: debug.println(debug.LEVEL_FINEST, 'orca.keyEcho: event string not handled: %s' % event_string) return None settings.enableActionKeys.println(debug.LEVEL_FINEST, 'orca.keyEcho: speaking: %s' % event_string) orca_state.lastKeyEchoTime = time.time() speech.speakKeyEvent(event_string, eventType) def _setClickCount(inputEvent): '''Sets the count of the number of clicks a user has made to one of the non-modifier keys on the keyboard. Note that this looks at the event_string (keysym) instead of hw_code (keycode) because the Java platform gives us completely different keycodes for keys. Arguments: - inputEvent: the current input event. ''' lastInputEvent = orca_state.lastNonModifierKeyEvent if inputEvent.type == pyatspi.KEY_RELEASED_EVENT: pass elif not isinstance(inputEvent, KeyboardEvent): orca_state.clickCount = 0 elif not isinstance(lastInputEvent, KeyboardEvent): orca_state.clickCount = 1 elif lastInputEvent.event_string != inputEvent.event_string or lastInputEvent.modifiers != inputEvent.modifiers: orca_state.clickCount = 1 elif inputEvent.time - lastInputEvent.time < settings.doubleClickTimeout: if orca_state.clickCount < 3: orca_state.clickCount += 1 else: orca_state.clickCount = 1 def _processKeyCaptured(event): '''Called when a new key event arrives and orca_state.capturingKeys=True. (used for key bindings redefinition) ''' if event.type == 0: if isModifierKey(event.event_string) or isLockingKey(event.event_string): return True keymap = gtk.gdk.keymap_get_default() entries = keymap.get_entries_for_keycode(event.hw_code) event.event_string = gtk.gdk.keyval_name(entries[0][0]) if event.event_string.startswith('KP') and event.event_string != 'KP_Enter': name = gtk.gdk.keyval_name(entries[1][0]) if name.startswith('KP'): event.event_string = name orca_state.lastCapturedKey = event return False def _processKeyboardEvent(event): '''The primary key event handler for Orca. Keeps track of various attributes, such as the lastInputEvent. Also calls keyEcho as well as any local keybindings before passing the event on to the active presentation manager. This method is called synchronously from the AT-SPI registry and should be performant. In addition, it must return True if it has consumed the event (and False if not). Arguments: - event: an AT-SPI DeviceEvent Returns True if the event should be consumed. ''' global _orcaModifierPressed, _orcaModifierPressed orca_state.lastInputEventTimestamp = event.timestamp string = keyEventToString(event) debug.printInputEvent(debug.LEVEL_FINE, string) keyboardEvent = KeyboardEvent(event) if False: allPossibleKeysyms = [] for keysym in settings.orcaModifierKeys: allPossibleKeysyms.extend(keybindings.getAllKeysyms(keysym)) else: allPossibleKeysyms = settings.orcaModifierKeys isOrcaModifier = allPossibleKeysyms.count(keyboardEvent.event_string) > 0 if event.type == pyatspi.KEY_PRESSED_EVENT: speech.stop() if isOrcaModifier: _orcaModifierPressed = True if not (settings.learnModeEnabled) and orca_state.activeScript.echoKey(keyboardEvent): keyEcho(keyboardEvent) elif isOrcaModifier and keyboardEvent.type == pyatspi.KEY_RELEASED_EVENT: _orcaModifierPressed = False if _orcaModifierPressed: keyboardEvent.modifiers = keyboardEvent.modifiers | settings.ORCA_MODIFIER_MASK orca_state.lastInputEvent = keyboardEvent if not isModifierKey(keyboardEvent.event_string): _setClickCount(keyboardEvent) orca_state.lastNonModifierKeyEvent = keyboardEvent consumed = False try: if orca_state.capturingKeys: consumed = _processKeyCaptured(keyboardEvent) else: consumed = _keyBindings.consumeKeyboardEvent(None, keyboardEvent) if not consumed and _currentPresentationManager >= 0: consumed = _PRESENTATION_MANAGERS[_currentPresentationManager].processKeyboardEvent(keyboardEvent) if not consumed and settings.learnModeEnabled: if keyboardEvent.type == pyatspi.KEY_PRESSED_EVENT: clickCount = orca_state.activeScript.getClickCount() if isPrintableKey(keyboardEvent.event_string) and clickCount == 2: orca_state.activeScript.phoneticSpellCurrentItem(keyboardEvent.event_string) else: braille.displayMessage(keyboardEvent.event_string) event_string = keyboardEvent.event_string event_string = keynames.getKeyName(event_string) speech.speak(event_string) elif event.type == pyatspi.KEY_RELEASED_EVENT and keyboardEvent.event_string == 'Escape': exitLearnMode(keyboardEvent) consumed = True if not consumed and not isModifierKey(keyboardEvent.event_string) and keyboardEvent.type == pyatspi.KEY_PRESSED_EVENT: orca_state.bypassNextCommand = False except: debug.printException(debug.LEVEL_SEVERE) if not consumed: pass return isOrcaModifier def _processBrailleEvent(command): '''Called whenever a key is pressed on the Braille display. Arguments: - command: the BrlAPI command for the key that was pressed. Returns True if the event was consumed; otherwise False ''' consumed = False speech.stop() event = BrailleEvent(command) orca_state.lastInputEvent = event try: consumed = _PRESENTATION_MANAGERS[_currentPresentationManager].processBrailleEvent(event) except: debug.printException(debug.LEVEL_SEVERE) if not consumed and settings.learnModeEnabled: consumed = True return consumed def toggleSilenceSpeech(script = None, inputEvent = None): '''Toggle the silencing of speech. Returns True to indicate the input event has been consumed. ''' speech.stop() if settings.silenceSpeech: settings.silenceSpeech = False speech.speak(_('Speech enabled.')) else: speech.speak(_('Speech disabled.')) settings.silenceSpeech = True return True def loadUserSettings(script = None, inputEvent = None): '''Loads (and reloads) the user settings module, reinitializing things such as speech if necessary. Returns True to indicate the input event has been consumed. ''' global _userSettings if settings.useDBus: dbusserver.shutdown() httpserver.shutdown() speech.shutdown() braille.shutdown() mag.shutdown() if _currentPresentationManager >= 0: _PRESENTATION_MANAGERS[_currentPresentationManager].deactivate() time.sleep(1) reloaded = False if _userSettings: try: reload(_userSettings) reloaded = True except ImportError: debug.printException(debug.LEVEL_FINEST) except: None<EXCEPTION MATCH>ImportError debug.printException(debug.LEVEL_SEVERE) None<EXCEPTION MATCH>ImportError try: _userSettings = __import__('user-settings') except ImportError: debug.printException(debug.LEVEL_FINEST) except: debug.printException(debug.LEVEL_SEVERE) for key in _commandLineSettings: setattr(settings, key, _commandLineSettings[key]) if settings.enableSpeech: try: speech.init() if reloaded: speech.speak(_('Orca user settings reloaded.')) debug.println(debug.LEVEL_CONFIGURATION, 'Speech module has been initialized.') debug.printException(debug.LEVEL_SEVERE) debug.println(debug.LEVEL_SEVERE, 'Could not initialize connection to speech.') else: debug.println(debug.LEVEL_CONFIGURATION, 'Speech module has NOT been initialized.') if settings.enableBraille: try: braille.init(_processBrailleEvent, settings.tty) debug.printException(debug.LEVEL_WARNING) debug.println(debug.LEVEL_WARNING, 'Could not initialize connection to braille.') if settings.enableMagnifier: try: mag.init() debug.println(debug.LEVEL_CONFIGURATION, 'Magnification module has been initialized.') debug.printException(debug.LEVEL_SEVERE) debug.println(debug.LEVEL_SEVERE, 'Could not initialize connection to magnifier.') else: debug.println(debug.LEVEL_CONFIGURATION, 'Magnification module has NOT been initialized.') try: mouse_review.mouse_reviewer.toggle(on = settings.enableMouseReview) except NameError: pass for keyName in settings.orcaModifierKeys: if keyName == 'Caps_Lock': os.system('xmodmap -e "clear Lock"') if keyName in ('Caps_Lock', 'KP_Insert', 'Insert'): command = 'xmodmap -e "keysym %s = %s"' % (keyName, keyName) os.system(command) continue if _currentPresentationManager >= 0: _PRESENTATION_MANAGERS[_currentPresentationManager].activate() showMainWindowGUI() if settings.useDBus: dbusserver.init() httpserver.init() return True def showAppPreferencesGUI(script = None, inputEvent = None): '''Displays the user interace to configure the settings for a specific applications within Orca and set up those app-specific user preferences using a GUI. Returns True to indicate the input event has been consumed. ''' try: module = __import__(settings.appGuiPreferencesModule, globals(), locals(), [ '']) module.showPreferencesUI() except: debug.printException(debug.LEVEL_SEVERE) return True def showPreferencesGUI(script = None, inputEvent = None): '''Displays the user interace to configure Orca and set up user preferences using a GUI. Returns True to indicate the input event has been consumed. ''' try: module = __import__(settings.guiPreferencesModule, globals(), locals(), [ '']) module.showPreferencesUI() except: debug.printException(debug.LEVEL_SEVERE) return True def showMainWindowGUI(script = None, inputEvent = None): '''Displays the Orca main window. Returns True to indicate the input event has been consumed. ''' try: module = __import__(settings.mainWindowModule, globals(), locals(), [ '']) if settings.showMainWindow: module.showMainUI() else: module.hideMainUI() except: debug.printException(debug.LEVEL_SEVERE) return True def _showPreferencesConsole(script = None, inputEvent = None): '''Displays the user interace to configure Orca and set up user preferences via a command line interface. Returns True to indicate the input event has been consumed. ''' try: module = __import__(settings.consolePreferencesModule, globals(), locals(), [ '']) module.showPreferencesUI(_commandLineSettings) except: debug.printException(debug.LEVEL_SEVERE) return True def helpForOrca(script = None, inputEvent = None): '''Show Orca Help window (part of the GNOME Access Guide). Returns True to indicate the input event has been consumed. ''' props = { gnome.PARAM_APP_DATADIR: '/usr/share' } prog = gnome.program_init('orca', '1.0', properties = props) gnome.help_display_with_doc_id(prog, 'gnome-access-guide', 'gnome-access-guide', 'ats-2') return True def quitOrca(script = None, inputEvent = None): '''Quit Orca. Check if the user wants to confirm this action. If so, show the confirmation GUI otherwise just shutdown. Returns True to indicate the input event has been consumed. ''' if settings.quitOrcaNoConfirmation: shutdown() else: try: module = __import__(settings.quitModule, globals(), locals(), [ '']) module.showQuitUI() except: debug.printException(debug.LEVEL_SEVERE) return True def showFindGUI(script = None, inputEvent = None): '''Displays the user interace to perform an Orca Find. Returns True to indicate the input event has been consumed. ''' try: module = __import__(settings.findModule, globals(), locals(), [ '']) module.showFindUI() except: debug.printException(debug.LEVEL_SEVERE) _initialized = False def init(registry): '''Initialize the orca module, which initializes speech, braille, and mag modules. Also builds up the application list, registers for AT-SPI events, and creates scripts for all known applications. Returns True if the initialization procedure has run, or False if this module has already been initialized. ''' global _keyBindings, _initialized if _initialized: return False if settings.timeoutCallback and settings.timeoutTime > 0: signal.signal(signal.SIGALRM, settings.timeoutCallback) signal.alarm(settings.timeoutTime) _keyBindings = keybindings.KeyBindings() registry.registerEventListener(_onChildrenChanged, 'object:children-changed') registry.registerEventListener(_onMouseButton, 'mouse:button') loadUserSettings() masks = [] mask = 0 while mask <= 255: masks.append(mask) mask += 1 pyatspi.Registry.registerKeystrokeListener(_processKeyboardEvent, mask = masks, kind = (pyatspi.KEY_PRESSED_EVENT, pyatspi.KEY_RELEASED_EVENT)) if settings.timeoutCallback and settings.timeoutTime > 0: signal.alarm(0) _initialized = True return True def start(registry): '''Starts Orca. ''' global _PRESENTATION_MANAGERS if not _initialized: init(registry) if settings.timeoutCallback and settings.timeoutTime > 0: signal.signal(signal.SIGALRM, settings.timeoutCallback) signal.alarm(settings.timeoutTime) if not _PRESENTATION_MANAGERS: import focus_tracking_presenter _PRESENTATION_MANAGERS = [ focus_tracking_presenter.FocusTrackingPresenter()] _switchToPresentationManager(0) if settings.timeoutCallback and settings.timeoutTime > 0: signal.alarm(0) if settings.cacheValues: pyatspi.setCacheLevel(pyatspi.CACHE_PROPERTIES) registry.start() def die(exitCode = 1): os._exit(exitCode) def timeout(signum = None, frame = None): debug.println(debug.LEVEL_SEVERE, 'TIMEOUT: something has hung. Aborting.') debug.printStack(debug.LEVEL_ALL) die(50) def shutdown(script = None, inputEvent = None): '''Exits Orca. Unregisters any event listeners and cleans up. Also quits the bonobo main loop and resets the initialized state to False. Returns True if the shutdown procedure ran or False if this module was never initialized. ''' global _initialized if not _initialized: return False if settings.timeoutCallback and settings.timeoutTime > 0: signal.signal(signal.SIGALRM, settings.timeoutCallback) signal.alarm(settings.timeoutTime) speech.speak(_('Goodbye.')) braille.displayMessage(_('Goodbye.')) pyatspi.Registry.deregisterEventListener(_onChildrenChanged, 'object:children-changed') pyatspi.Registry.deregisterEventListener(_onMouseButton, 'mouse:button') if _currentPresentationManager >= 0: _PRESENTATION_MANAGERS[_currentPresentationManager].deactivate() if settings.enableSpeech: speech.shutdown() if settings.enableBraille: braille.shutdown() if settings.enableMagnifier or settings.enableMagLiveUpdating: mag.shutdown() pyatspi.Registry.stop() if settings.timeoutCallback and settings.timeoutTime > 0: signal.alarm(0) _initialized = False return True exitCount = 0 def shutdownOnSignal(signum, frame): global exitCount debug.println(debug.LEVEL_ALL, 'Shutting down and exiting due to signal = %d' % signum) debug.println(debug.LEVEL_ALL, 'Current stack is:') debug.printStack(debug.LEVEL_ALL) if exitCount: die(signum) else: exitCount += 1 if settings.timeoutCallback and settings.timeoutTime > 0: signal.signal(signal.SIGALRM, settings.timeoutCallback) signal.alarm(settings.timeoutTime) try: if _initialized: shutdown() else: speech.shutdown() shutdown() cleanExit = True except: cleanExit = False if settings.timeoutCallback and settings.timeoutTime > 0: signal.alarm(0) if not cleanExit: die(signum) def abortOnSignal(signum, frame): debug.println(debug.LEVEL_ALL, 'Aborting due to signal = %d' % signum) die(signum) def usage(): '''Prints out usage information.''' print _('Usage: orca [OPTION...]') print print '-?, --help ' + _('Show this help message') print '-v, --version %s' % platform.version print '-l, --list-apps ' + _('Print the known running applications') print '-s, --setup, --gui-setup ' + _('Set up user preferences') print '-t, --text-setup ' + _('Set up user preferences (text version)') print '-n, --no-setup ' + _('Skip set up of user preferences') print '-u, --user-prefs-dir=dirname ' + _('Use alternate directory for user preferences') print '-e, --enable=[speech' + '|' + 'braille' + '|' + 'braille-monitor' + '|' + 'magnifier' + '|' + 'main-window' + ']', _('Force use of option') print '-d, --disable=[' + 'speech' + '|' + 'braille' + '|' + 'braille-monitor' + '|' + 'magnifier' + '|' + 'main-window' + ']', _('Prevent use of option') print '-q, --quit ' + _('Quits Orca (if shell script used)') print print _('If Orca has not been previously set up by the user, Orca\nwill automatically launch the preferences set up unless\nthe -n or --no-setup option is used.') print print _('WARNING: suspending Orca, e.g. by pressing Control-Z, from\nan AT-SPI enabled shell (such as gnome-terminal), can also\nsuspend the desktop until Orca is killed.') print print _('Report bugs to orca-list@gnome.org.') def main(): '''The main entry point for Orca. The exit codes for Orca will loosely be based on signals, where the exit code will be the signal used to terminate Orca (if a signal was used). Otherwise, an exit code of 0 means normal completion and an exit code of 50 means Orca exited because of a hang.''' settings.timeoutCallback = timeout signal.signal(signal.SIGHUP, shutdownOnSignal) signal.signal(signal.SIGINT, shutdownOnSignal) signal.signal(signal.SIGTERM, shutdownOnSignal) signal.signal(signal.SIGQUIT, shutdownOnSignal) signal.signal(signal.SIGSEGV, abortOnSignal) desktopRunning = False try: if gtk.gdk.display_get_default(): desktopRunning = True except: pass bypassSetup = False setupRequested = False showGUI = False arglist = sys.argv[1:] if len(arglist) == 1: arglist = arglist[0].split() try: (opts, args) = getopt.getopt(arglist, '?stnvld:e:u:', [ 'help', 'user-prefs-dir=', 'enable=', 'disable=', 'setup', 'gui-setup', 'text-setup', 'no-setup', 'list-apps', 'version']) for opt, val in opts: if opt in ('-u', '--user-prefs-dir'): userPrefsDir = val.strip() try: os.chdir(userPrefsDir) settings.userPrefsDir = userPrefsDir debug.printException(debug.LEVEL_FINEST) if opt in ('-e', '--enable'): feature = val.strip() if feature == 'speech': _commandLineSettings['enableSpeech'] = True elif feature == 'braille': _commandLineSettings['enableBraille'] = True elif feature == 'braille-monitor': _commandLineSettings['enableBrailleMonitor'] = True elif feature == 'magnifier': _commandLineSettings['enableMagnifier'] = True elif feature == 'main-window': _commandLineSettings['showMainWindow'] = True else: usage() die(2) if opt in ('-d', '--disable'): feature = val.strip() if feature == 'speech': _commandLineSettings['enableSpeech'] = False elif feature == 'braille': _commandLineSettings['enableBraille'] = False elif feature == 'braille-monitor': _commandLineSettings['enableBrailleMonitor'] = False elif feature == 'magnifier': _commandLineSettings['enableMagnifier'] = False elif feature == 'main-window': _commandLineSettings['showMainWindow'] = False else: usage() die(2) if opt in ('-s', '--gui-setup', '--setup'): setupRequested = True showGUI = desktopRunning if opt in ('-t', '--text-setup'): setupRequested = True showGUI = False if opt in ('-n', '--no-setup'): bypassSetup = True if opt in ('-?', '--help'): usage() die(0) if opt in ('-v', '--version'): print 'Orca %s' % platform.version die(0) if opt in ('-l', '--list-apps'): apps = filter((lambda x: x is not None), pyatspi.Registry.getDesktop(0)) for app in apps: print app.name die(0) continue except: debug.printException(debug.LEVEL_OFF) usage() die(2) a11yEnabled = settings.isAccessibilityEnabled() if not bypassSetup and not a11yEnabled: _showPreferencesConsole() die() if setupRequested and not bypassSetup and not showGUI: _showPreferencesConsole() if not desktopRunning: print 'Cannot start Orca because it cannot connect' print 'to the Desktop. Please make sure the DISPLAY' print 'environment variable has been set.' return 1 userprefs = settings.userPrefsDir sys.path.insert(0, userprefs) sys.path.insert(0, '') init(pyatspi.Registry) try: message = _('Welcome to Orca.') speech.speak(message) braille.displayMessage(message) except: desktopRunning debug.printException(debug.LEVEL_SEVERE) if setupRequested and not bypassSetup and showGUI: showPreferencesGUI() elif not _userSettings and not bypassSetup: if desktopRunning: showPreferencesGUI() else: _showPreferencesConsole() start(pyatspi.Registry) return 0 if __name__ == '__main__': sys.exit(main())